//=====================================================================
//
// basic_test.cpp - KCP基础功能测试
//
// 编译命令：g++ basic_test.cpp ../ikcp.c -o basic_test -std=c++11
//
//=====================================================================

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <vector>

#include "../ikcp.h"

// 简单的数据传输模拟
std::vector<std::vector<char> > network_queue[2]; // 0->1, 1->0

// KCP输出回调函数
int udp_output(const char *buf, int len, ikcpcb *kcp, void *user) {
    int from = *(int*)user;
    int to = 1 - from; // 0->1, 1->0
    
    std::vector<char> packet(buf, buf + len);
    network_queue[to].push_back(packet);
    
    printf("[网络] 从端点%d发送到端点%d，包大小: %d字节\n", from, to, len);
    return 0;
}

// 获取当前时间（毫秒）
unsigned int get_millisec() {
    return (unsigned int)(clock() * 1000 / CLOCKS_PER_SEC);
}

void test_basic_communication() {
    printf("=== KCP基础通信测试 ===\n\n");
    
    // 创建两个KCP端点
    int peer0 = 0, peer1 = 1;
    ikcpcb *kcp0 = ikcp_create(0x12345678, &peer0);
    ikcpcb *kcp1 = ikcp_create(0x12345678, &peer1);
    
    // 设置输出回调
    ikcp_setoutput(kcp0, udp_output);
    ikcp_setoutput(kcp1, udp_output);
    
    // 配置KCP参数（快速模式）
    ikcp_wndsize(kcp0, 32, 32);
    ikcp_wndsize(kcp1, 32, 32);
    ikcp_nodelay(kcp0, 1, 10, 2, 1);
    ikcp_nodelay(kcp1, 1, 10, 2, 1);
    
    printf("1. 单向通信测试\n");
    const char* message = "Hello from KCP endpoint 0!";
    printf("   端点0发送: \"%s\"\n", message);
    ikcp_send(kcp0, message, strlen(message));
    
    // 模拟网络传输和处理
    char buffer[1024];
    for (int step = 0; step < 100; step++) {
        unsigned int current_time = step * 10; // 每步10ms
        
        // 更新KCP状态
        ikcp_update(kcp0, current_time);
        ikcp_update(kcp1, current_time);
        
        // 处理网络队列中的包
        // 处理发送给端点1的包
        if (!network_queue[1].empty()) {
            auto& packet = network_queue[1].front();
            printf("   端点1接收网络包，大小: %zu字节\n", packet.size());
            ikcp_input(kcp1, packet.data(), packet.size());
            network_queue[1].erase(network_queue[1].begin());
        }
        
        // 处理发送给端点0的包
        if (!network_queue[0].empty()) {
            auto& packet = network_queue[0].front();
            printf("   端点0接收网络包，大小: %zu字节\n", packet.size());
            ikcp_input(kcp0, packet.data(), packet.size());
            network_queue[0].erase(network_queue[0].begin());
        }
        
        // 尝试接收数据
        int recv_len = ikcp_recv(kcp1, buffer, sizeof(buffer));
        if (recv_len > 0) {
            buffer[recv_len] = 0;
            printf("   端点1接收到: \"%s\"\n", buffer);
            break;
        }
    }
    
    printf("\n2. 双向通信测试\n");
    const char* reply = "Hello back from endpoint 1!";
    printf("   端点1回复: \"%s\"\n", reply);
    ikcp_send(kcp1, reply, strlen(reply));
    
    // 处理回复
    for (int step = 0; step < 100; step++) {
        unsigned int current_time = 1000 + step * 10;
        
        ikcp_update(kcp0, current_time);
        ikcp_update(kcp1, current_time);
        
        // 处理网络队列
        if (!network_queue[0].empty()) {
            auto& packet = network_queue[0].front();
            ikcp_input(kcp0, packet.data(), packet.size());
            network_queue[0].erase(network_queue[0].begin());
        }
        
        if (!network_queue[1].empty()) {
            auto& packet = network_queue[1].front();
            ikcp_input(kcp1, packet.data(), packet.size());
            network_queue[1].erase(network_queue[1].begin());
        }
        
        int recv_len = ikcp_recv(kcp0, buffer, sizeof(buffer));
        if (recv_len > 0) {
            buffer[recv_len] = 0;
            printf("   端点0接收到回复: \"%s\"\n", buffer);
            break;
        }
    }
    
    printf("\n3. 大数据传输测试\n");
    char large_data[1000];
    for (int i = 0; i < 1000; i++) {
        large_data[i] = 'A' + (i % 26);
    }
    
    printf("   端点0发送1000字节数据...\n");
    ikcp_send(kcp0, large_data, 1000);
    
    int total_received = 0;
    for (int step = 0; step < 200; step++) {
        unsigned int current_time = 2000 + step * 10;
        
        ikcp_update(kcp0, current_time);
        ikcp_update(kcp1, current_time);
        
        // 处理网络队列
        while (!network_queue[1].empty()) {
            auto& packet = network_queue[1].front();
            ikcp_input(kcp1, packet.data(), packet.size());
            network_queue[1].erase(network_queue[1].begin());
        }
        
        while (!network_queue[0].empty()) {
            auto& packet = network_queue[0].front();
            ikcp_input(kcp0, packet.data(), packet.size());
            network_queue[0].erase(network_queue[0].begin());
        }
        
        int recv_len = ikcp_recv(kcp1, buffer, sizeof(buffer));
        if (recv_len > 0) {
            total_received += recv_len;
            printf("   端点1接收到%d字节，总计: %d字节\n", recv_len, total_received);
            if (total_received >= 1000) break;
        }
    }
    
    printf("\n4. 状态信息\n");
    printf("   端点0等待发送: %d个包\n", ikcp_waitsnd(kcp0));
    printf("   端点1等待发送: %d个包\n", ikcp_waitsnd(kcp1));
    
    // 清理
    ikcp_release(kcp0);
    ikcp_release(kcp1);
    
    printf("\n=== 基础通信测试完成 ===\n");
}

void test_different_modes() {
    printf("\n=== KCP不同模式对比测试 ===\n\n");
    
    const char* modes[] = {"默认模式", "普通模式", "快速模式"};
    int mode_params[][4] = {
        {0, 10, 0, 0}, // 默认模式
        {0, 10, 0, 1}, // 普通模式
        {1, 10, 2, 1}  // 快速模式
    };
    
    for (int mode = 0; mode < 3; mode++) {
        printf("测试%s:\n", modes[mode]);
        
        // 清空网络队列
        network_queue[0].clear();
        network_queue[1].clear();
        
        int peer0 = 0, peer1 = 1;
        ikcpcb *kcp0 = ikcp_create(0x11223344 + mode, &peer0);
        ikcpcb *kcp1 = ikcp_create(0x11223344 + mode, &peer1);
        
        ikcp_setoutput(kcp0, udp_output);
        ikcp_setoutput(kcp1, udp_output);
        
        ikcp_wndsize(kcp0, 32, 32);
        ikcp_wndsize(kcp1, 32, 32);
        
        // 设置模式参数
        ikcp_nodelay(kcp0, mode_params[mode][0], mode_params[mode][1], 
                     mode_params[mode][2], mode_params[mode][3]);
        ikcp_nodelay(kcp1, mode_params[mode][0], mode_params[mode][1], 
                     mode_params[mode][2], mode_params[mode][3]);
        
        // 发送测试数据
        const char* test_msg = "Mode test message";
        ikcp_send(kcp0, test_msg, strlen(test_msg));
        
        int steps_needed = 0;
        char buffer[1024];
        
        for (int step = 0; step < 200; step++) {
            unsigned int current_time = step * 10;
            
            ikcp_update(kcp0, current_time);
            ikcp_update(kcp1, current_time);
            
            // 处理网络包
            while (!network_queue[1].empty()) {
                auto& packet = network_queue[1].front();
                ikcp_input(kcp1, packet.data(), packet.size());
                network_queue[1].erase(network_queue[1].begin());
            }
            
            while (!network_queue[0].empty()) {
                auto& packet = network_queue[0].front();
                ikcp_input(kcp0, packet.data(), packet.size());
                network_queue[0].erase(network_queue[0].begin());
            }
            
            int recv_len = ikcp_recv(kcp1, buffer, sizeof(buffer));
            if (recv_len > 0) {
                steps_needed = step + 1;
                buffer[recv_len] = 0;
                printf("   接收成功，用时: %d步 (%dms)\n", steps_needed, steps_needed * 10);
                break;
            }
        }
        
        if (steps_needed == 0) {
            printf("   接收失败\n");
        }
        
        ikcp_release(kcp0);
        ikcp_release(kcp1);
    }
}

int main() {
    printf("=== KCP框架测试程序 ===\n\n");
    
    test_basic_communication();
    test_different_modes();
    
    printf("\n=== 所有测试完成 ===\n");
    return 0;
}